package Net::FTP::Client;

use JIP::ToolSet; # load my commonly-used modules in a single import
use parent qw( Class::Base Class::Accessor::Fast );

use Net::FTP;
use Net::FTP::Client::Listing::Creator;
use Carp qw( croak );
use Readonly qw( Readonly );
use English qw( -no_match_vars );

__PACKAGE__->mk_ro_accessors( qw(
    _host
    _timeout
    _user
    _pass
    _connection
    _listingDecorator
) );

Readonly my $UNIX_LISTING => qr/^[a-z-]{10}          # drwxr-xr-x
                               \s+\d*                # 1
                               (?:\s+\w+){2}         # ftp ftp
                               \s+\d+                # 0
                               \s+\w+\s+\d+\s+[\d:]+ # Feb 15 17:34
                               \s+.+$                # linux_format
                               /x;

Readonly my $DOS_LISTING => qr/^\d\d-\d\d-\d\d\s+\d\d:\d\d\wM # date and time
                              \s+                             # some space
                              (?:<DIR>|\d+)                   # dir or size
                              \s+                             # some more space
                              .+$                             # file name
                              /x;

sub init {
    my( $self, $config ) = @ARG;

    $self->{'_host'} = $config->{'host'}
        or croak 'required parameter "host" not defined';

    $self->{'_timeout'} = $config->{'timeout'}
        or croak 'required parameter "timeout" not defined';

    $self->{'_user'} = $config->{'user'}
        or croak 'required parameter "user" not defined';

    $self->{'_pass'} = $config->{'pass'}
        or croak 'required parameter "pass" not defined';

    $self->_initConnection;
    $self->_initListingDecorator; # всегда после установления connection

    return $self;
}

sub dir {
    my( $self, $dirLocation ) = @ARG;

    my @dirListing = $self->_connection->dir( $dirLocation ) or return;

    return $self->_listingDecorator->parseDir( @dirListing ) or return;
}

sub _initConnection {
    my $self = shift;

    $self->{'_connection'} = Net::FTP->new(
        $self->{'_host'},
        Timeout => $self->{'_timeout'}
    ) or croak 'cannot connect to server '. $EVAL_ERROR;

    $self->{'_connection'}->login( $self->{'_user'}, $self->{'_pass'} )
        or croak 'authentification error: '. $self->{'_connection'}->message;
}

sub _initListingDecorator {
    my $self = shift;

    given ( ( $self->{'_connection'}->dir('') )[0] ) {
        when( $UNIX_LISTING ) {
            $self->{'_listingDecorator'} = Net::FTP::Client::Listing::Creator->create('Unix')
        }

        when( $DOS_LISTING ) {
            $self->{'_listingDecorator'} = Net::FTP::Client::Listing::Creator->create('DOS')
        }

        default { croak 'unknown system' }
    }
}

1;
